package com.android.panballgame;

import java.util.Timer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.annotation.SuppressLint;
import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.widget.Toast;

public class PBGameRenderer implements Renderer{

	//실제 도형
	Context context;	
	private PBBackground background; //배경
	private PBVector [] vec; //코인 위치 좌표
	private PBCoin [] coin; //코인(수행해야될 미션)
	private PBBall ball; //공
	
	//경계 도형
	private PBCircle CirBall; //공
	private PBCircle[] CirCoin; //코인
	private PBCircle CirHole; //골인 구멍	
	private PBRectangle [] rec; //벽(장애물)
	
	//가속도 계산 변수
	int oriX, oriY= 0;
	float sx, sy, vx, vy = 0;	
	
	//조건변수
	boolean drawball; //공 골인 유무
			
	// 생성자
	@SuppressLint("NewApi")
	public PBGameRenderer(Context context){
		
		if(PBEngine.useDb == 0){
			PBEngine.ballx = 0.25f;
			PBEngine.bally = 6.19f;
		}
		
		this.context = context;
		//각 도형 생성
		background = new PBBackground();
		vec = new PBVector[5];		
		coin = new PBCoin[5];
		ball = new PBBall();

		for(int i = 0; i < 5; i++)
			coin[i] = new PBCoin();
		
		int ran;
		if(PBEngine.useDb == 1)
			ran = PBEngine.coinLoc;
		else{
			ran = 1 + (int)(Math.random() * 5);
			PBEngine.coinLoc = ran;
		}
		switch(ran){
			case 1 :
				vec[0] = new PBVector(4.1f, 0.5f);
				vec[1] = new PBVector(2.3f, 4.0f);
				vec[2] = new PBVector(2.3f, 5.8f);
				vec[3] = new PBVector(7.7f, 5.8f);
				vec[4] = new PBVector(9.5f, 0.5f);
				break;
			case 2 :
				vec[0] = new PBVector(4.1f, 0.5f);
				vec[1] = new PBVector(9.5f, 5.8f);
				vec[2] = new PBVector(2.3f, 5.8f);
				vec[3] = new PBVector(6.0f, 0.5f);
				vec[4] = new PBVector(9.5f, 2.5f);
				break;
			case 3 :
			 	vec[0] = new PBVector(0.5f, 2.0f);
				vec[1] = new PBVector(4.1f, 2.0f);
				vec[2] = new PBVector(6.3f, 4.0f);
				vec[3] = new PBVector(9.5f, 5.8f);
				vec[4] = new PBVector(9.5f, 0.5f);
				break;
			case 4 :
				vec[0] = new PBVector(4.1f, 0.5f);
				vec[1] = new PBVector(2.3f, 4.0f);
				vec[2] = new PBVector(0.5f, 0.5f);
				vec[3] = new PBVector(7.7f, 5.8f);
				vec[4] = new PBVector(11.3f, 2.8f);
				break;
			case 5 :
				vec[0] = new PBVector(0.5f, 3.0f);
				vec[1] = new PBVector(7.3f, 4.1f);
				vec[2] = new PBVector(6.3f, 2.3f);
				vec[3] = new PBVector(10.5f, 5.8f);
				vec[4] = new PBVector(11.3f, 2.0f);
				break;
		
		}
		
		//경계 도형 생성
		CirBall = new PBCircle((PBEngine.ballx + 0.475f), (PBEngine.bally + 0.475f), 0.475f); //공
		CirCoin = new PBCircle[5]; //코인
		for(int i = 0; i < 5; i++){
			CirCoin[i] = new PBCircle((vec[i].x + 0.475f), (vec[i].y + 0.475f), 0.475f);
		}		
		CirHole = new PBCircle(11.795f, 0.965f, 0.25f); //구멍
	
		rec = new PBRectangle[9]; //벽(사각형)
		rec[0] = new  PBRectangle(1.78f,2.0f,0.2f,5.04f);
		rec[1] = new  PBRectangle(1.98f, 5.27f, 3.59f, 0.2f);
		rec[2] = new  PBRectangle(5.38f, 3.5f, 0.2f, 1.97f);
		rec[3] = new  PBRectangle(5.38f, 3.5f, 3.8f, 0.2f);
		rec[4] = new  PBRectangle(3.58f, 0.15f, 0.2f, 3.56f);
		rec[5] = new  PBRectangle(5.38f, 0.15f, 0.2f, 1.77f);
		rec[6] = new  PBRectangle(8.98f, 5.44f, 0.2f, 1.6f);
		rec[7] = new  PBRectangle(10.76f, 0.15f, 0.2f, 5.26f);
		rec[8] = new  PBRectangle(7.43f, 1.78f, 3.32f, 0.2f);
		
		//조건변수 초기화
		drawball = true;		

		if(PBEngine.useDb != 1){
			for(int i = 0; i < 5; i++)
				PBEngine.drawcoin[i] = 1;			
		}
	}
	
		@SuppressLint("NewApi")
		@Override
		public void onDrawFrame(GL10 gl) {

			try{
				Thread.sleep(PBEngine.GAME_THREAD_FPS_SLEEP);
			}catch (InterruptedException e){
				e.printStackTrace();
			}
		
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);//버퍼 초기화			
			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA); //투명 영역 적용
			
			for(int i = 0; i < 5; i++){//코인이 먹힌 경우
				if(PBOverlapTester.overlapCircles(CirBall, CirCoin[i]))			
					if(PBEngine.drawcoin[i] == 1){
						PBEngine.drawcoin[i] = 0;
						PBGame.sound(1);
						PBEngine.remain--;
						}
			}
			
			if(PBOverlapTester.pointInCircle(CirHole, CirBall.center))//공이 골인 지점에 들어간 경우
				if(drawball){
					if(PBEngine.remain <= 0){ //남은 과제 수가 0이면
						PBGame.sound(2);
						drawball = false;
						Timer timer = new Timer();
						timer.schedule(new PBDelay(), 1000);
						PBEngine.STATUS = PBEngine.CLEAR;
						PBEngine.WAIT = true;
					}
					else
						PBEngine.HOLE = true;
				}
				
			background(gl);
			coin(gl);			
			if(drawball)	
				ball(gl);

		}
		
		
		//벽(장애물)에 부딪혔을 때
		private boolean obstacleS(){//남쪽
			boolean crash = false;
			
			for(int i = 0; i < 9; i++){				
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 1){
					if( Math.abs(CirBall.center.y - rec[i].lowerLeft.y) >= Math.abs(CirBall.center.x - rec[i].lowerLeft.x))
						PBEngine.bally = rec[i].lowerLeft.y - CirBall.radius - CirBall.radius;
					else
						crash = true;
				}			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 2){
					PBEngine.ballx = rec[i].lowerLeft.x - CirBall.radius - CirBall.radius;
					crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 3){
					if( Math.abs(CirBall.center.y - (rec[i].lowerLeft.y + rec[i].height)) >= Math.abs(CirBall.center.x - rec[i].lowerLeft.x))
						PBEngine.bally =  rec[i].lowerLeft.y + rec[i].height; 
					else
						crash = true;
				}			
			}
			
			return crash;
		}
		
		private boolean obstacleN(){//북쪽
			boolean crash = false;
			
			for(int i = 0; i < 9; i++){			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 7){
					if( Math.abs(CirBall.center.y - rec[i].lowerLeft.y) >= Math.abs(CirBall.center.x - (rec[i].lowerLeft.x + rec[i].width)))
						PBEngine.bally = rec[i].lowerLeft.y - CirBall.radius - CirBall.radius;
					else
						crash = true;
				}			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 8){
					PBEngine.ballx = rec[i].lowerLeft.x + rec[i].width;
					crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 9){
					if( Math.abs(CirBall.center.y - (rec[i].lowerLeft.y + rec[i].height)) >= Math.abs(CirBall.center.x - (rec[i].lowerLeft.x + rec[i].width)))
						PBEngine.bally =  rec[i].lowerLeft.y + rec[i].height; 
					else
						crash = true;
				}			
			}	
			return crash;			
		}
		
		private boolean obstacleE(){//동쪽
			boolean crash = false;
			
			for(int i = 0; i < 9; i++){
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 1){
					if( Math.abs(CirBall.center.y - rec[i].lowerLeft.y) < Math.abs(CirBall.center.x - rec[i].lowerLeft.x))
						PBEngine.ballx = rec[i].lowerLeft.x - CirBall.radius - CirBall.radius;
					else
						crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 4){
					PBEngine.bally = rec[i].lowerLeft.y - CirBall.radius - CirBall.radius;
					crash = true;
				}			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 7){
					if( Math.abs(CirBall.center.y - rec[i].lowerLeft.y) < Math.abs(CirBall.center.x - (rec[i].lowerLeft.x + rec[i].width)))
						PBEngine.ballx = rec[i].lowerLeft.x + rec[i].width;
					else
						crash = true;
				}			
			}			
			return crash;			
		}
		
		private boolean obstacleW(){//서쪽
			boolean crash = false;
			
			for(int i = 0; i < 9; i++){			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 3){ 
					if( Math.abs(CirBall.center.y - (rec[i].lowerLeft.y + rec[i].height)) < Math.abs(CirBall.center.x - rec[i].lowerLeft.x))
						PBEngine.ballx = rec[i].lowerLeft.x - CirBall.radius - CirBall.radius;
					else
						crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 6){ 
					PBEngine.bally =  rec[i].lowerLeft.y + rec[i].height; 
					crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 9){ 
					if( Math.abs(CirBall.center.y - (rec[i].lowerLeft.y + rec[i].height)) < Math.abs(CirBall.center.x - (rec[i].lowerLeft.x + rec[i].width)))
						PBEngine.ballx = rec[i].lowerLeft.x + rec[i].width;
					else
						crash = true;
				}			
			}			
			return crash;			
		}
		
		//가속도 이용해서 공의 속도 계산 및 적용
		private void acc(){
			//s= v0t + 1/2at², v = v0 + at 
			//기울임에 따라 공 이동
			
			// y 좌표 조정
			if(-9.8<=PBGame.accX && PBGame.accX<-0.1 && oriY != 2){
				if(PBEngine.bally > 6.10f){ //판 오른쪽 테두리
					PBEngine.bally = 6.10f;
					sy = 0;
					vy = 0;
				}
				else{					
					if(obstacleE()){ //장애물에 부딪혔을 때 obstacle 함수를 불러 처리함.
						sy = 0;
						vy = 0;
					}else{
						sy = vy + (0.5f)*PBGame.accX*(0.016f)*(0.015f);
						vy = vy + PBGame.accX*(0.016f)*(0.015f);
						PBEngine.bally = PBEngine.bally - sy; 
					}					
				}
				oriY = 1;				
			}else	if(-9.8<=PBGame.accX && PBGame.accX<-0.1 && oriY ==2 ){
				sy = 0;
				vy = 0;
				oriY = 1;
			}else if(0.1<PBGame.accX && PBGame.accX<=9.8 && oriY != 1){				
				if(PBEngine.bally < 0.15f){ //왼쪽 테두리
					PBEngine.bally = 0.15f;
					sy = 0;
					vy = 0;
				}
				else{
					if(obstacleW()){
						sy = 0;
						vy = 0;
					}else{
						sy = vy + (0.5f)*PBGame.accX*(0.016f)*(0.015f);
						vy = vy + PBGame.accX*(0.016f)*(0.015f);
						PBEngine.bally = PBEngine.bally - sy;						
					}
				}
				oriY = 2;	
			}else if(0.1<PBGame.accX && PBGame.accX<=9.8 && oriY == 1){
				sy = 0;
				vy = 0;
				oriY = 2;
			}else{
				sy = 0;
				vy = 0;
				oriY = 0;
			}
			
			
			// x 좌표 조정	
			if(-9.8<=PBGame.accY && PBGame.accY<-0.1 && oriX != 2 ){
				if(PBEngine.ballx < 0.15f){ //상단 테두리
					PBEngine.ballx = 0.15f;
					sx = 0;
					vx = 0;
				}
				else{
					if(obstacleN()){ 
						sx = 0;
						vx = 0;
					}else{
						sx = vx + (0.5f)*PBGame.accY*(0.016f)*(0.015f);
						vx = vx + PBGame.accY*(0.016f)*(0.015f);
						PBEngine.ballx = PBEngine.ballx + sx;						
					}
				}
				oriX = 1;
			}else if(-9.8<=PBGame.accY && PBGame.accY<-0.1 && oriX == 2 ){
				sx = 0;
				vx = 0;
				oriX = 1;
			}else if(0.1<PBGame.accY && PBGame.accY<=9.8 && oriX != 1){
				if(PBEngine.ballx > 11.68f){ //하단 테두리
					PBEngine.ballx = 11.68f;
					sx = 0;
					vx = 0;
				}
				else{
					if(obstacleS()){
						sx = 0;
						vx = 0;
					}else{
						sx = vx + (0.5f)*PBGame.accY*(0.016f)*(0.015f);
						vx = vx + PBGame.accY*(0.016f)*(0.015f);
						PBEngine.ballx = PBEngine.ballx + sx;						
					}
				}
				oriX = 2;
			}else if(0.1<PBGame.accY && PBGame.accY<=9.8 && oriX == 1){
				sx = 0;
				vx = 0;
				oriX = 2;
			}			
			else{
				sx = 0;
				vx = 0;
				oriX = 0;
			}
		}
		
		private void ball(GL10 gl){
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glPushMatrix();
						
			acc();//가속도 적용
			CirBall.trans(PBEngine.ballx+0.475f, PBEngine.bally+0.475f);//공의 경계도형을 공의 움직임에 맞춰 이동
		   			
			gl.glScalef(0.078f, 0.138f, 0.1f);
			gl.glTranslatef(PBEngine.ballx, PBEngine.bally, 2f);
			gl.glMatrixMode(GL10.GL_TEXTURE);
			gl.glLoadIdentity();			
			ball.draw(gl);			
			gl.glPopMatrix();
			gl.glLoadIdentity();
		}
		
		private void background(GL10 gl){
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();			
			gl.glPushMatrix();
			gl.glScalef(1f, 1f, 1f);
			gl.glTranslatef(0f, 0f, 0f);			
			gl.glMatrixMode(GL10.GL_TEXTURE);
			gl.glLoadIdentity();			
			background.draw(gl);
			gl.glPopMatrix();
			gl.glLoadIdentity();			
		}
		
		private void coin(GL10 gl){			
			for(int i=0; i < 5; i++){
				if(PBEngine.drawcoin[i] == 1){
					gl.glMatrixMode(GL10.GL_MODELVIEW);
					gl.glLoadIdentity();
					gl.glPushMatrix();
					gl.glScalef(0.078f, 0.138f, 0.1f);
					gl.glTranslatef(vec[i].x, vec[i].y, 2f);					
					gl.glMatrixMode(GL10.GL_TEXTURE);
					gl.glLoadIdentity();					
					coin[i].draw(gl);			
					gl.glPopMatrix();
					gl.glLoadIdentity();
				}
			}
		}
		
		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
			gl.glViewport(0, 0, width, height);
			float wf = (float) width / (float) 1280;
			float hf = (float) height / (float) 720;			
			gl.glMatrixMode(GL10.GL_PROJECTION);
			gl.glLoadIdentity();
			gl.glOrthof(0f, 1f * wf, 0f, 1f * hf, -1f, 1f); //직교 2D 형태
		}

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			gl.glEnable(GL10.GL_TEXTURE_2D);
			gl.glClearDepthf(1.0f);
			gl.glEnable(GL10.GL_DEPTH_TEST);
			gl.glDepthFunc(GL10.GL_LEQUAL);		
			
		    background.loadTexture(gl, PBEngine.BACKGROUND_LAYER_ONE, PBEngine.context);		
		    ball.loadTexture(gl, PBEngine.PLAYER_BALL, PBEngine.context);
		    for(int i=0; i<5; i++){
		    	coin[i].loadTexture(gl, PBEngine.PLAYER_COIN, PBEngine.context);  
		    }
		}
		
		
}